package com.zx.rabbitmq.springboot.service;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.UUID;

/**
 * @author Zx
 * @date 2021/5/31 17:36
 */
@Service
public class OrderService {

    private final RabbitTemplate rabbitTemplate;

    public OrderService(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    /**
     * 模拟用户下订单
     *
     * @param userId
     * @param productId
     * @param num
     */
    public void makeOrder(String userId, String productId, int num) {
        // 1: 根据商品ID查询库存是否充足
        // 2: 保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("生成订单: " + orderId);
        // 3: 通过MQ消息队列完成消息的分发

        // 交换机命名: 类型/业务/交换机
        String exchangeName = "fanout_order_exchange";
        //
        String routingKey = "";
        /*
         * 参数1: 交换机
         * 参数2: 路由key/queue队列名称
         * 参数3: 消息内容
         */
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
    }

    /**
     * 模拟用户下订单
     *
     * @param userId
     * @param productId
     * @param num
     */
    public void makeOrderDirect(String userId, String productId, int num) {
        // 1: 根据商品ID查询库存是否充足
        // 2: 保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("生成订单: " + orderId);
        // 3: 通过MQ消息队列完成消息的分发

        // 交换机命名: 类型/业务/交换机
        String exchangeName = "direct_order_exchange";
        //
        String routingKey = "";
        /*
         * 参数1: 交换机
         * 参数2: 路由key/queue队列名称
         * 参数3: 消息内容
         */
        rabbitTemplate.convertAndSend(exchangeName, "email", orderId);
        rabbitTemplate.convertAndSend(exchangeName, "sms", orderId);
    }

    /**
     * 模拟用户下订单
     *
     * @param userId
     * @param productId
     * @param num
     */
    public void makeOrderTopic(String userId, String productId, int num) {
        // 1: 根据商品ID查询库存是否充足
        // 2: 保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("生成订单: " + orderId);
        // 3: 通过MQ消息队列完成消息的分发

        // 交换机命名: 类型/业务/交换机
        String exchangeName = "topic_order_exchange";
        //
        String routingKey = "email.sms.xxx";
        /*
         * 参数1: 交换机
         * 参数2: 路由key/queue队列名称
         * 参数3: 消息内容
         */
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
    }

    /**
     * 模拟用户下订单
     * <p>设置队列过期时间</p>
     *
     * @param userId
     * @param productId
     * @param num
     */
    public void makeOrderTTL(String userId, String productId, int num) {
        // 1: 根据商品ID查询库存是否充足
        // 2: 保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("生成订单: " + orderId);
        // 3: 通过MQ消息队列完成消息的分发

        // 交换机命名: 类型/业务/交换机
        String exchangeName = "ttl_direct_exchange";
        //
        String routingKey = "ttl";
        /*
         * 参数1: 交换机
         * 参数2: 路由key/queue队列名称
         * 参数3: 消息内容
         */
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
    }

    /**
     * 模拟用户下订单
     * <p>设置单条消息过期时间</p>
     *
     * @param userId
     * @param productId
     * @param num
     */
    public void makeOrderTTLMessage(String userId, String productId, int num) {
        // 1: 根据商品ID查询库存是否充足
        // 2: 保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("生成订单: " + orderId);
        // 3: 通过MQ消息队列完成消息的分发

        // 交换机命名: 类型/业务/交换机
        String exchangeName = "ttl_direct_exchange";
        //
        String routingKey = "ttlMessage";

        // 给消息设置过期时间
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            /**
             * Change (or replace) the message.
             *
             * @param message the message.
             * @return the message.
             * @throws AmqpException an exception.
             */
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration("5000");
                message.getMessageProperties().setContentEncoding("UTF-8");
                return message;
            }
        };
        /*
         * 参数1: 交换机
         * 参数2: 路由key/queue队列名称
         * 参数3: 消息内容
         */
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId, messagePostProcessor);
    }
}
